package com.sna.snaapplication.service.LogReg.impl;


import com.sna.snaapplication.entity.R;
import com.sna.snaapplication.entity.usercore.core.dto.UserDTO;
import com.sna.snaapplication.entity.usercore.login.LoginBody;
import com.sna.snaapplication.entity.usercore.login.MyUserDetails;
import com.sna.snaapplication.mapper.UserMapper;
import com.sna.snaapplication.service.LogReg.LoginService;
import com.sna.snaapplication.utils.JwtUtil;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /*
    * 用户登录
    * */
    @Autowired
    AuthenticationManager manager;

    public R login(LoginBody user, HttpSession session){
        /*
         * 创建了UsernamePasswordAuthenticationToken对象，
         * 其中包含用户输入的明文用户名和密码
         * */
        UsernamePasswordAuthenticationToken uToken=new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword());
        UserDTO userDto=new UserDTO();
        try
        {

            Authentication auth= manager.authenticate(uToken);

            MyUserDetails myUserDetails = (MyUserDetails) auth.getPrincipal();
            System.out.println("myuserdetails:"+myUserDetails);

            BeanUtils.copyProperties(myUserDetails,userDto);

            // 生成 JWT 令牌
            Map<String,Object> claims=new HashMap<>();
            claims.put("userId",userDto.getId());
            claims.put("username",userDto.getUsername());
            String token = JwtUtil.genToken(claims);

            //把token存储到redis中
            ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
            operations.set(token,token, 1, TimeUnit.HOURS);


            //使用session保存登录状态,注意改变跨域设置，使能够在前后端分离的项目中使用 sesssion
            //同时axios使用Credentials=true属性
            SecurityContextHolder.getContext().setAuthentication(auth);
            session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,SecurityContextHolder.getContext());

            Map<String, Object> response = new HashMap<>();
            response.put("user", userDto);
            response.put("token", token);
            return R.ok(response);
        }
        catch (Exception ex){

            System.out.println("登录失败:12"+ex.getMessage());
            return R.fail("登录失败!");
        }
    }
}
